<?php
/**
 * Service_Booking
 *
 * Класс Service_Booking осуществляет работу с API сайта Booking.com
 *
 * @author Egorov Aleksandr (slamer86@gmail.com)
 */
class Service_Booking {
	
	public $rows = 1000;
	public $offset = null;
	public $lastChange = null;
	public $showTest = 0;
	public $arrCountryCodes = array();
	public $arrLanguageCodes = array();
	public $arrFields = array();
	public $arrCityIds = array();
	public $arrDistrictIds = array();
	public $arrRegionIds = array();
	public $arrCreditCardIds = array();
	public $arrChainIds = array();
	public $arrClasses = array();
	public $arrHotelIds = array();
	public $arrDescriptionTypeIds = array();
	public $arrFacilityTypeIds = array();
	public $arrHotelFacilityTypeIds = array();
	public $arrTypes = array();
	public $arrRoomTypeIds = array();
	public $arrRoomIds = array();
	public $arrRoomFacilityTypeIds = array();
	public $test = 1;	
		
	public $arrSystemLang = array('en', 'ru');

	/**
	 * Получаем адрес для вызова API
	 * @param string $functionName - название функции
	 */
	public function getBookingPath($functionName, $https = 0) {
	  return 'http' . ($https ? 's' : '') . '://' . BOOKING_LOGIN . ':' . BOOKING_PASS . '@distribution-xml.booking.com/xml/bookings.' . $functionName;
	}

	private function processResult($arrResult) {
		Service_Debug::setDebug();
		//$arrResult = json_decode(json_encode((array) simplexml_load_string($arrResult)),1);
		if (isset($arrResult['fault'])) return $arrResult;
		if (!isset($arrResult['result'])) return array();
		$arrTmp = $arrResult['result'];
		unset($arrResult['result']);
		if (!isset($arrTmp[0])) $arrResult[0] = $arrTmp;
		else $arrResult = $arrTmp;
		
		return $arrResult;
	}

	/**
	 * Получаем страны
	 *
	 * @return array - массив данных
	 */
	public function getCountries() {
		$objCurl = new Service_Curl();
		$arrResult = $objCurl->httpRequest('GET', $this->getBookingPath('getCountries'), array(
			'countrycodes' => $this->arrCountryCodes, 
			'languagecodes' => $this->arrLanguageCodes, 
			'rows' => $this->rows, 
			'offset' => $this->offset
		));
		return $this->processResult($arrResult);
	}
	
	/**
	 * Получаем и сохраняем страны
	 *
	 */
	public function parseCountries() {
		$objDB = Service_Database::instance();
		foreach ($this->arrSystemLang as $lang) {
			$this->arrLanguageCodes = array($lang);
			$arrCountries = $this->getCountries();
			if (empty($arrCountries) || isset($arrCountries['fault'])) continue;
			foreach ($arrCountries as $arrCountry) {
				$stmt = "INSERT INTO country (country_code, area_" . $lang . ", country_name_" . $lang . ") 
								 VALUES ('" . $arrCountry['countrycode'] . "', '" . $arrCountry['area'] . "', '" . $arrCountry['name'] . "')
								 ON DUPLICATE KEY UPDATE area_" . $lang . " = '" . $arrCountry['area'] . "', country_name_" . $lang . " = '" . $arrCountry['name'] . "'";
				$objDB->query($stmt);
				$objCountry = new Country($arrCountry['countrycode']);
				$objCountry->updateCountryFinalName();
			}			
		}
		$stmt = "SELECT country.country_code, country.country_name_en FROM country WHERE country_url IS NULL";
		$arrCountries = $objDB->select($stmt);
		foreach ($arrCountries as $arrCountry) {
			$countryUrl = Service_Generate::generateAlias($arrCountry['country_name_en']);
			$stmt = "UPDATE country 
			SET country.country_url = '" . $countryUrl . "'
			WHERE country.country_code = '" . $arrCountry['country_code'] . "'";
			$objDB->query($stmt);
			$stmt = "UPDATE city 
			SET city.country_url = '" . $countryUrl . "'
			WHERE city.country_code = '" . $arrCountry['country_code'] . "'";
			$objDB->query($stmt);	
			$stmt = "UPDATE hotel 
			SET hotel.country_url = '" . $countryUrl . "'
			WHERE hotel.country_code = '" . $arrCountry['country_code'] . "'";			
			$objDB->query($stmt);
		}
	}	
	
	/**
	 * Получаем города
	 *
	 * @return array - массив данных
	 */
	public function getCities() {
		$objCurl = new Service_Curl();
		$arrResult = $objCurl->httpRequest('GET', $this->getBookingPath('getCities'), array(
			'city_ids' => $this->arrCityIds,
			'countrycodes' => $this->arrCountryCodes, 
			'fields' => $this->arrFields, 
			'languagecodes' => $this->arrLanguageCodes, 
			'rows' => $this->rows, 
			'offset' => $this->offset
		));
		return $this->processResult($arrResult);
	}
	
	/**
	 * Получаем и сохраняем города
	 *
	 */
	public function parseCities() {
		Pressure::setStart();
		$objDB = Service_Database::instance();
		$stmt = "SELECT country_code FROM country ORDER BY last_parse, country_code";
		$arrCountryCodes = $objDB->selectSimpleArray($stmt);
		foreach ($arrCountryCodes as $countryCode) {
			$this->arrCountryCodes = array($countryCode);
			foreach ($this->arrSystemLang as $lang) {
				$count = 0;
				$this->arrLanguageCodes = array($lang);		
				do {			
					$this->offset = $count;	
					$arrCities = $this->getCities();
					if (empty($arrCities) || isset($arrCities['fault'])) break;
					foreach ($arrCities as $arrCity) {
						$arrCity['name'] = Service_Escape::absolutelyEscapeString($arrCity['name']);
						$stmt = "INSERT INTO city (`ID_city`,`country_code`,`latitude`,`longitude`,`city_name_" . $lang . "`) 
										 VALUES ('" . $arrCity['city_id'] . "', '" . $arrCity['countrycode'] . "', '" . $arrCity['latitude'] . "', '" . $arrCity['longitude'] . "', '" . $arrCity['name'] . "')
										 ON DUPLICATE KEY UPDATE `city_name_" . $lang . "` = '" . $arrCity['name'] . "'";
						$objDB->query($stmt);		
						$objCity = new City($arrCity['city_id']);
						$objCity->updateCityFinalName();						
					}
					$count += sizeof($arrCities);
				}
				while (sizeof($arrCities) == $this->rows);
			}
			$objDB->update('country', array('last_parse' => Service_Date::gLocalTime2BD()), array('country_code' => $countryCode));
			$objDB->query($stmt);
			$time = Pressure::calculateCurrentDuration();
			if ($time > 10) {
				$stmt = "SELECT city.ID_city, city.city_name_en FROM city WHERE city_url IS NULL";
				$arrCities = $objDB->select($stmt);
				foreach ($arrCities as $arrCity) {
					$cityUrl = Service_Generate::generateAlias($arrCity['city_name_en']);
					$stmt = "UPDATE city 
					SET city.city_url = '" . $cityUrl . "'
					WHERE city.ID_city = '" . $arrCity['ID_city'] . "'";
					$objDB->query($stmt);
					$stmt = "UPDATE hotel 
					SET hotel.city_url = '" . $cityUrl . "'
					WHERE hotel.ID_city = '" . $arrCity['ID_city'] . "'";			
					$objDB->query($stmt);
				}
				return false;			
			}
		}
	}

	/**
	 * Получаем районы
	 *
	 * @return array - массив данных
	 */
	public function getDistricts() {
		$objCurl = new Service_Curl();
		$arrResult = $objCurl->httpRequest('GET', $this->getBookingPath('getDistricts'), array(
			'district_ids' => $this->arrDistrictIds, 
			'city_ids' => $this->arrCityIds, 
			'countrycodes' => $this->arrCountryCodes, 
			'fields' => $this->arrFields, 
			'languagecodes' => $this->arrLanguageCodes, 
			'rows' => $this->rows, 
			'offset' => $this->offset, 
			'last_change' => $this->lastChange
		));
		return $this->processResult($arrResult);
	}
	
	/**
	 * Получаем и сохраняем районы
	 *
	 */
	public function parseDistricts() {
		$objDB = Service_Database::instance();
		foreach ($this->arrSystemLang as $lang) {
			$count = 0;
			$this->arrLanguageCodes = array($lang);		
			do {			
				$this->offset = $count;	
				$arrDistricts = $this->getDistricts();
				if (empty($arrDistricts) || isset($arrDistricts['fault'])) break;
				foreach ($arrDistricts as $arrDistrict) {
					if (isset($arrDistrict['code'])) continue;
					$arrDistrict['name'] = Service_Escape::absolutelyEscapeString($arrDistrict['name']);
					$stmt = "INSERT INTO district (`ID_district`,`country_code`,`ID_city`,`district_name_" . $lang . "`) 
									 VALUES ('" . $arrDistrict['district_id'] . "', '" . $arrDistrict['countrycode'] . "', '" . $arrDistrict['city_id'] . "', '" . $arrDistrict['name'] . "')
									 ON DUPLICATE KEY UPDATE `district_name_" . $lang . "` = '" . $arrDistrict['name'] . "'";
					$objDB->query($stmt);
				}
				$count += sizeof($arrDistricts);
			}
			while (sizeof($arrDistricts) == $this->rows);
		}
	}	
	
	/**
	 * Получаем регионы
	 *
	 * @return array - массив данных
	 */
	public function getRegions($arrRegionTypes = array()) {
		$objCurl = new Service_Curl();
		$arrResult = $objCurl->httpRequest('GET', $this->getBookingPath('getRegions'), array(
			'region_ids' => $this->arrRegionIds,
			'region_types' => $arrRegionTypes, 
			'countrycodes' => $this->arrCountryCodes, 
			'fields' => $this->arrFields, 
			'languagecodes' => $this->arrLanguageCodes, 
			'rows' => $this->rows, 
			'offset' => $this->offset, 
			'last_change' => $this->lastChange			
		));
		return $this->processResult($arrResult);
	}
	
	/**
	 * Получаем и сохраняем регионы
	 *
	 */
	public function parseRegions() {
		$objDB = Service_Database::instance();
		foreach ($this->arrSystemLang as $lang) {
			$count = 0;
			$this->arrLanguageCodes = array($lang);		
			do {			
				$this->offset = $count;	
				$arrRegions = $this->getRegions();	
				if (empty($arrRegions) || isset($arrRegions['fault'])) break;
				/*if (!empty($arrRegions)) {
					$strRegionIds = Service_ArrayConverter::getColumnAsString($arrRegions, 'region_id');
					$stmt = "SELECT ID_photo FROM room_photo WHERE ID_photo IN (" . $strRegionIds . ")";
					$arrRegionIds = $objDB->selectSimpleArray($stmt);
				}		
				else $arrRegionIds = array();*/	
				foreach ($arrRegions as $arrRegion) {
					//if (in_array($arrRegion['region_id'], $arrRegionIds)) continue;
					$arrRegion['name'] = Service_Escape::absolutelyEscapeString($arrRegion['name']);
					$stmt = "INSERT INTO region (`ID_region`,`country_code`,`region_type`,`region_name_" . $lang . "`) 
									 VALUES ('" . $arrRegion['region_id'] . "', '" . $arrRegion['countrycode'] . "', '" . $arrRegion['region_type'] . "', '" . $arrRegion['name'] . "')
									 ON DUPLICATE KEY UPDATE `region_name_" . $lang . "` = '" . $arrRegion['name'] . "'";
					$objDB->query($stmt);
				}
				$count += sizeof($arrRegions);
			}
			while (sizeof($arrRegions) == $this->rows);
		}
	}		
	
	/**
	 * Получаем типы кредитных карт
	 *
	 * @return array - массив данных
	 */
	public function getCreditCardTypes() {
		$objCurl = new Service_Curl();
		$arrResult = $objCurl->httpRequest('GET', $this->getBookingPath('getCreditcardTypes'), array(
			'creditcard_ids' => $this->arrCreditCardIds, 
			'fields' => $this->arrFields
		));
		return $this->processResult($arrResult);
	}

	
	/**
	 * Получаем и сохраняем типы кредитных карт
	 *
	 */
	public function parseCreditCardTypes() {
		$objDB = Service_Database::instance();			
		$arrCreditCards = $this->getCreditCardTypes();
		if (empty($arrCreditCards) || isset($arrCreditCards['fault'])) return false;
		foreach ($arrCreditCards as $arrCreditCard) {
			$stmt = "INSERT INTO credit_card (`ID_credit_card`,`credit_card_name`,`is_bookable`) 
							 VALUES ('" . $arrCreditCard['creditcard_id'] . "', '" . $arrCreditCard['name'] . "', '" . $arrCreditCard['bookable'] . "')
							 ON DUPLICATE KEY
							 UPDATE 
							 `credit_card_name` = VALUES(`credit_card_name`),
							 `is_bookable` = VALUES(`is_bookable`)";
			$objDB->query($stmt);
		}
	}				
	
	/**
	 * Получаем типы кредитных карт
	 *
	 * @return array - массив данных
	 */
	public function getCreditCards() {
		$objCurl = new Service_Curl();
		$arrResult = $objCurl->httpRequest('GET', $this->getBookingPath('getCreditcards'), array(
			'creditcard_ids' => $this->arrCreditCardIds, 
			'city_ids' => $this->arrCityIds, 
			'classes' => $this->arrClasses, 
			'countrycodes' => $this->arrCountryCodes, 
			'fields' => $this->arrFields, 
			'hotel_ids' => $this->arrHotelIds, 
			'rows' => $this->rows, 
			'offset' => $this->offset, 
			'last_change' => $this->lastChange,
			'show_test' => $this->showTest,  
		));
		return $this->processResult($arrResult);
	}
	
	/**
	 * Получаем и сохраняем типы кредитных карт
	 *
	 */
	public function parseCreditCards() {
		$objDB = Service_Database::instance();			
		if (!empty($this->arrHotelIds)) {
			$stmt = "DELETE FROM hotel_credit_card WHERE ID_hotel IN (" . join(',', $this->arrHotelIds) . ")";
			$objDB->query($stmt);				
		}						
		$count = 0;
		do {			
			$this->offset = $count;	
			$arrCreditCards = $this->getCreditCards();
			if (empty($arrCreditCards) || isset($arrCreditCards['fault'])) break;
			foreach ($arrCreditCards as $arrCreditCard) {
				$stmt = "INSERT INTO hotel_credit_card (`ID_hotel`,`ID_credit_card`,`is_bookable`,`is_payable`) 
								 VALUES ('" . $arrCreditCard['hotel_id'] . "', '" . $arrCreditCard['creditcard_id'] . "', '" . $arrCreditCard['bookable'] . "', '" . $arrCreditCard['payable'] . "')
								 ON DUPLICATE KEY
								 UPDATE 
								 `is_bookable` = VALUES(`is_bookable`),
								 `is_payable` = VALUES(`is_payable`)";
				$objDB->query($stmt);
			}
			$count += sizeof($arrCreditCards);
			
		}
		while (sizeof($arrCreditCards) == $this->rows);
	}			
	
	/**
	 * Получаем типы сетей гостиниц
	 *
	 * @return array - массив данных
	 */
	public function getChainTypes() {
		$objCurl = new Service_Curl();
		$arrResult = $objCurl->httpRequest('GET', $this->getBookingPath('getChainTypes'), array(
			'chain_ids' => $this->arrChainIds, 
			'fields' => $this->arrFields
		));
		return $this->processResult($arrResult);
	}
	
	/**
	 * Получаем и сохраняем типы кредитных карт
	 *
	 */
	public function parseChainTypes() {
		$objDB = Service_Database::instance();			
		$arrChainTypes = $this->getChainTypes();
		if (empty($arrChainTypes) || isset($arrChainTypes['fault'])) return false;
		foreach ($arrChainTypes as $arrChainType) {
			$arrChainType['name'] = Service_Escape::absolutelyEscapeString($arrChainType['name']);
			$stmt = "INSERT INTO chain (`ID_chain`,`chain_name`) 
							 VALUES ('" . $arrChainType['chain_id'] . "', '" . $arrChainType['name'] . "')
							 ON DUPLICATE KEY
							 UPDATE 
							 `chain_name` = VALUES(`chain_name`)";
			$objDB->query($stmt);
		}
	}		

	/**
	 * Получаем связи гостиниц и сетей
	 *
	 * @return array - массив данных
	 */
	public function getChains() {
		$objCurl = new Service_Curl();
		$arrResult = $objCurl->httpRequest('GET', $this->getBookingPath('getChains'), array(
			'chain_ids' => $this->arrChainIds,
			'city_ids' => $this->arrCityIds, 
			'classes' => $this->arrClasses, 
			'countrycodes' => $this->arrCountryCodes, 
			'fields' => $this->arrFields, 
			'hotel_ids' => $this->arrHotelIds, 
			'rows' => $this->rows, 
			'offset' => $this->offset,
			'show_test' => $this->showTest,  
			'last_change' => $this->lastChange
		));
		return $this->processResult($arrResult);
	}
	
	/**
	 * Получаем и сохраняем связи гостиниц и сетей
	 *
	 */
	public function parseChains() {
		$objDB = Service_Database::instance();
		$count = 0;
		do {					
			$arrChains = $this->getChains();
			if (empty($arrChains) || isset($arrChains['fault'])) break;
			foreach ($arrChains as $arrChain) {
				$stmt = "UPDATE hotel
								 SET ID_chain = '" . $arrChain['chain_id'] . "'
								 WHERE ID_hotel = '" . $arrChain['hotel_id'] . "'";
				$objDB->query($stmt);
			}
			$count += sizeof($arrChains);
		}
		while (sizeof($arrChains) == $this->rows);			
	}			
	
	/**
	 * Получаем связи гостиниц и регионов
	 *
	 * @return array - массив данных
	 */
	public function getRegionHotels() {
		$objCurl = new Service_Curl();
		$arrResult = $objCurl->httpRequest('GET', $this->getBookingPath('getRegionHotels'), array(
			'region_ids' => $this->arrRegionIds, 
			'classes' => $this->arrClasses, 
			'countrycodes' => $this->arrCountryCodes, 
			'fields' => $this->arrFields, 
			'hotel_ids' => $this->arrHotelIds, 
			'rows' => $this->rows, 
			'offset' => $this->offset, 
			'last_change' => $this->lastChange
		));
		return $this->processResult($arrResult);
	}
	
	/**
	 * Получаем и сохраняем связи гостиниц и регионов
	 *
	 */
	public function parseRegionHotels() {
		$objDB = Service_Database::instance();
		$count = 0;
		do {					
			$arrRegionHotels = $this->getRegionHotels();		
			if (empty($arrRegionHotels) || isset($arrRegionHotels['fault'])) break;
			foreach ($arrRegionHotels as $arrRegionHotel) {
				if ($arrRegionHotel['region_id'] == 4289) continue;
				$stmt = "UPDATE hotel
								 SET ID_region = '" . $arrRegionHotel['region_id'] . "'
								 WHERE ID_hotel = '" . $arrRegionHotel['hotel_id'] . "'";
				$objDB->query($stmt);
			}
			$count += sizeof($arrRegionHotels);
		}
		while (sizeof($arrRegionHotels) == $this->rows);			
	}		

	/**
	 * Получаем связи гостиниц и регионов
	 *
	 * @return array - массив данных
	 */
	public function getChainHotels() {
		$objCurl = new Service_Curl();
		$arrResult = $objCurl->httpRequest('GET', $this->getBookingPath('getChainHotels'), array(
			'chain_ids' => $this->arrChainIds,
			'city_ids' => $this->arrCityIds, 
			'classes' => $this->arrClasses, 
			'countrycodes' => $this->arrCountryCodes, 
			'fields' => $this->arrFields, 
			'hotel_ids' => $this->arrHotelIds, 
			'rows' => $this->rows, 
			'offset' => $this->offset, 
			'show_test' => $this->showTest,
			'last_change' => $this->lastChange
		));
		return $this->processResult($arrResult);
	}
	
	/**
	 * Получаем и сохраняем связи гостиниц и регионов
	 *
	 */
	public function parseChainHotels() {
		$objDB = Service_Database::instance();
		$count = 0;
		do {					
			$arrChainHotels = $this->getChainHotels();
			if (empty($arrChainHotels) || isset($arrChainHotels['fault'])) break;
			foreach ($arrChainHotels as $arrChainHotel) {
				$stmt = "UPDATE hotel
								 SET ID_chain = '" . $arrChainHotel['chain_id'] . "'
								 WHERE ID_hotel = '" . $arrChainHotel['hotel_id'] . "'";
				$objDB->query($stmt);
			}
			$count += sizeof($arrChainHotels);
		}
		while (sizeof($arrChainHotels) == $this->rows);			
	}		
	
	/**
	 * Получаем связи гостиниц и районов
	 *
	 * @return array - массив данных
	 */
	public function getDistrictHotels() {
		$objCurl = new Service_Curl();
		$arrResult = $objCurl->httpRequest('GET', $this->getBookingPath('getDistrictHotels'), array(
			'city_ids' => $this->arrCityIds, 
			'district_ids' => $this->arrDistrictIds, 
			'classes' => $this->arrClasses, 
			'countrycodes' => $this->arrCountryCodes, 
			'fields' => $this->arrFields, 
			'hotel_ids' => $this->arrHotelIds, 
			'rows' => $this->rows, 
			'offset' => $this->offset,
		 	'show_test' => $this->showTest,
			'last_change' => $this->lastChange
		));
		return $this->processResult($arrResult);
	}
	
	/**
	 * Получаем и сохраняем связи гостиниц и районов
	 *
	 */
	public function parseDistrictHotels() {
		$objDB = Service_Database::instance();
		$count = 0;
		do {					
			$arrDistrictHotels = $this->getDistrictHotels();
			if (empty($arrDistrictHotels) || isset($arrDistrictHotels['fault'])) break;
			foreach ($arrDistrictHotels as $arrDistrictHotel) {
				$stmt = "UPDATE hotel
								 SET ID_district = '" . $arrDistrictHotel['district_id'] . "'
								 WHERE ID_hotel = '" . $arrDistrictHotel['hotel_id'] . "'";
				$objDB->query($stmt);
			}
			$count += sizeof($arrDistrictHotels);
		}
		while (sizeof($arrDistrictHotels) == $this->rows);			
	}

	/**
	 * Получаем типы сетей гостиниц
	 *
	 * @return array - массив данных
	 */
	public function getHotelDescriptionTypes() {
		$objCurl = new Service_Curl();
		$arrResult = $objCurl->httpRequest('GET', $this->getBookingPath('getHotelDescriptionTypes'), array(
			'descriptiontype_ids' => $this->arrDescriptionTypeIds, 
			'languagecodes' => $this->arrLanguageCodes, 
			'fields' => $this->arrFields
		));
		return $this->processResult($arrResult);
	}
	
	/**
	 * Получаем и сохраняем типы сетей гостиниц
	 *
	 */
	public function parseHotelDescriptionTypes() {
		$objDB = Service_Database::instance();	
		foreach ($this->arrSystemLang as $lang) {
			$this->arrLanguageCodes = array($lang);				
			$arrHotelDescriptionTypes = $this->getHotelDescriptionTypes();
			if (empty($arrHotelDescriptionTypes) || isset($arrHotelDescriptionTypes['fault'])) continue;
			foreach ($arrHotelDescriptionTypes as $arrHotelDescriptionType) {
				$arrHotelDescriptionType['name'] = Service_Escape::absolutelyEscapeString($arrHotelDescriptionType['name']);
				$stmt = "INSERT INTO description_type (`ID_description_type`,`description_type_name_" . $lang . "`) 
								 VALUES ('" . $arrHotelDescriptionType['descriptiontype_id'] . "', '" . $arrHotelDescriptionType['name'] . "')
								 ON DUPLICATE KEY UPDATE `description_type_name_" . $lang . "` = '" . $arrHotelDescriptionType['name'] . "'";
				$objDB->query($stmt);
			}
		}
	}


	/**
	 * Получаем фотографии описания отелей
	 *
	 * @return array - массив данных
	 */
	public function getHotelDescriptionPhotos() {
		$objCurl = new Service_Curl();
		$arrResult = $objCurl->httpRequest('GET', $this->getBookingPath('getHotelDescriptionPhotos'), array(
			'hotel_ids' => $this->arrHotelIds, 
			'city_ids' => $this->arrCityIds, 
			'classes' => $this->arrClasses, 
			'countrycodes' => $this->arrCountryCodes, 
			'fields' => $this->arrFields,  
			'rows' => $this->rows, 
			'offset' => $this->offset, 
			'show_test' => $this->showTest,
			'last_change' => $this->lastChange)
		);
		return $this->processResult($arrResult);
	}
	
	/**
	 * Получаем и сохраняем фотографии описания отелей
	 *
	 */
	public function parseHotelDescriptionPhotos() {
		$objDB = Service_Database::instance();	
		if (!empty($this->arrHotelIds)) {
			$stmt = "DELETE FROM hotel_description_photo WHERE ID_hotel IN (" . join(',', $this->arrHotelIds) . ")";
			$objDB->query($stmt);				
		}						
		$count = 0;
		do {			
			$this->offset = $count;	
			$arrHotelDescriptionPhotos = $this->getHotelDescriptionPhotos();
			if (empty($arrHotelDescriptionPhotos) || isset($arrHotelDescriptionPhotos['fault'])) break;
			/*if (!empty($arrHotelDescriptionPhotos)) {
				$strHotelDescriptionPhotoIds = Service_ArrayConverter::getColumnAsString($arrHotelDescriptionPhotos, 'photo_id');
				$stmt = "SELECT ID_photo FROM room_photo WHERE ID_photo IN (" . $strHotelDescriptionPhotoIds . ")";
				$arrHotelDescriptionPhotoIds = $objDB->selectSimpleArray($stmt);
			}		
			else $arrHotelDescriptionPhotoIds = array();*/			
			foreach ($arrHotelDescriptionPhotos as $arrHotelDescriptionPhoto) {
				//if (in_array($arrHotelDescriptionPhoto['photo_id'], $arrHotelDescriptionPhotoIds)) continue;
				$stmt = "INSERT INTO hotel_description_photo (`ID_photo`,`ID_hotel`,`ID_description_type`,`url_original`,`url_max_300`,`url_square_60`) 
								 VALUES ('" . $arrHotelDescriptionPhoto['photo_id'] . "', '" . $arrHotelDescriptionPhoto['hotel_id'] . "', '" . $arrHotelDescriptionPhoto['descriptiontype_id'] . "', '" . $arrHotelDescriptionPhoto['url_original'] . "', '" . $arrHotelDescriptionPhoto['url_max300'] . "', '" . $arrHotelDescriptionPhoto['url_square60'] . "')
								 ON DUPLICATE KEY
								 UPDATE 
								 `ID_hotel` = VALUES(`ID_hotel`),
								 `ID_description_type` = VALUES(`ID_description_type`),
								 `url_original` = VALUES(`url_original`),
								 `url_max_300` = VALUES(`url_max_300`),
								 `url_square_60` = VALUES(`url_square_60`)
								 ";
				$objDB->query($stmt);
			}
			$count += sizeof($arrHotelDescriptionPhotos);
			
		}
		while (sizeof($arrHotelDescriptionPhotos) == $this->rows);
		
	}

	/**
	 * Получаем описания отелей
	 *
	 * @return array - массив данных
	 */
	public function getHotelDescriptions() {
		$objCurl = new Service_Curl();
		$arrResult = $objCurl->httpRequest('GET', $this->getBookingPath('getHotelDescriptionTranslations'), array(
			'hotel_ids' => $this->arrHotelIds, 
			'city_ids' => $this->arrCityIds, 
			'classes' => $this->arrClasses, 
			'countrycodes' => $this->arrCountryCodes,
			'languagecodes' => $this->arrLanguageCodes, 
			'fields' => $this->arrFields, 
			'descriptiontype_ids' => $this->arrDescriptionTypeIds, 
			'rows' => $this->rows, 
			'offset' => $this->offset, 
			'show_test' => $this->showTest,		
			'last_change' => $this->lastChange)
		);
		return $this->processResult($arrResult);
	}
	
	/**
	 * Получаем и сохраняем описания отелей
	 *
	 */
	public function parseHotelDescriptions() {
		$objDB = Service_Database::instance();	
		if (!empty($this->arrHotelIds)) {
			$stmt = "DELETE FROM hotel_description WHERE ID_hotel IN (" . join(',', $this->arrHotelIds) . ")";
			$objDB->query($stmt);				
		}								
		foreach ($this->arrSystemLang as $lang) {
			$count = 0;
			$this->arrLanguageCodes = array($lang);		
			do {			
				$this->offset = $count;	
				$arrHotelDescriptions = $this->getHotelDescriptions();
				if (empty($arrHotelDescriptions) || isset($arrHotelDescriptions['fault'])) break;
				foreach ($arrHotelDescriptions as $arrHotelDescription) {
					$arrHotelDescription['description'] = Service_Escape::absolutelyEscapeString($arrHotelDescription['description']);
					$stmt = "INSERT INTO hotel_description (`ID_hotel`,`ID_description_type`,`hotel_description_" . $lang . "`) 
									 VALUES ('" . $arrHotelDescription['hotel_id'] . "', '" . $arrHotelDescription['descriptiontype_id'] . "', '" . $arrHotelDescription['description'] . "')
									 ON DUPLICATE KEY UPDATE `hotel_description_" . $lang . "` = '" . $arrHotelDescription['description'] . "'";
					$objDB->query($stmt);
					if ($arrHotelDescription['descriptiontype_id'] == 6) {
						$stmt = "UPDATE `hotel` 
						  SET `xml_description_" . $lang . "` = '" . $arrHotelDescription['description'] . "'
						  WHERE `ID_hotel` = '" . $arrHotelDescription['hotel_id'] . "'";
						$objDB->query($stmt);
					} 
				}
				$count += sizeof($arrHotelDescriptions);
				
			}
			while (sizeof($arrHotelDescriptions) == $this->rows);
		}
	}		
	
	/**
	 * Получаем типы услуг
	 *
	 * @return array - массив данных
	 */
	public function getFacilityTypes() {
		$objCurl = new Service_Curl();
		$arrResult = $objCurl->httpRequest('GET', $this->getBookingPath('getFacilityTypes'), array(
			'facilitytype_ids' => $this->arrFacilityTypeIds, 
			'languagecodes' => $this->arrLanguageCodes, 
			'fields' => $this->arrFields
		));
		return $this->processResult($arrResult);
	}
	
	/**
	 * Получаем и сохраняем типы услуг
	 *
	 */
	public function parseFacilityTypes() {
		$objDB = Service_Database::instance();	
		foreach ($this->arrSystemLang as $lang) {
			$this->arrLanguageCodes = array($lang);				
			$arrFaclilityTypes = $this->getFacilityTypes();
			if (empty($arrFaclilityTypes) || isset($arrFaclilityTypes['fault'])) continue;
			foreach ($arrFaclilityTypes as $arrFaclilityType) {
				$arrFaclilityType['name'] = Service_Escape::absolutelyEscapeString($arrFaclilityType['name']);
				$stmt = "INSERT INTO facility_type (`ID_facility_type`,`facility_type_name_" . $lang . "`) 
								 VALUES ('" . $arrFaclilityType['facilitytype_id'] . "', '" . $arrFaclilityType['name'] . "')
								 ON DUPLICATE KEY UPDATE `facility_type_name_" . $lang . "` = '" . $arrFaclilityType['name'] . "'";
				$objDB->query($stmt);
			}
		}
	}

	/**
	 * Получаем типы услуг отелей
	 *
	 * @return array - массив данных
	 */
	public function getHotelFacilityTypes() {
		$objCurl = new Service_Curl();
		$arrResult = $objCurl->httpRequest('GET', $this->getBookingPath('getHotelFacilityTypes'), array(
			'facilitytype_ids' => $this->arrFacilityTypeIds,
			'hotelfacilitytype_ids' => $this->arrHotelFacilityTypeIds, 
			'fields' => $this->arrFields, 
			'languagecodes' => $this->arrLanguageCodes, 
			'types' => $this->arrTypes			
		));
		return $this->processResult($arrResult);
	}
	
	/**
	 * Получаем и сохраняем типы услуг отелей
	 *
	 */
	public function parseHotelFacilityTypes() {
		$objDB = Service_Database::instance();
		foreach ($this->arrSystemLang as $lang) {
			$this->arrLanguageCodes = array($lang);		
			$arrHotelFacilityTypes = $this->getHotelFacilityTypes();
			if (empty($arrHotelFacilityTypes) || isset($arrHotelFacilityTypes['fault'])) continue;
			foreach ($arrHotelFacilityTypes as $arrHotelFacilityType) {
				$arrHotelFacilityType['name'] = Service_Escape::absolutelyEscapeString($arrHotelFacilityType['name']);
				$stmt = "INSERT INTO hotel_facility_type (`ID_hotel_facility_type`,`ID_facility_type`,`hotel_facility_type_name_" . $lang . "`,`hotel_facility_type_type`) 
								 VALUES ('" . $arrHotelFacilityType['hotelfacilitytype_id'] . "', '" . $arrHotelFacilityType['facilitytype_id'] . "', '" . $arrHotelFacilityType['name'] . "', '" . $arrHotelFacilityType['type'] . "')
								 ON DUPLICATE KEY UPDATE `hotel_facility_type_name_" . $lang . "` = '" . $arrHotelFacilityType['name'] . "'";
				$objDB->query($stmt);
			}
		}
	}			
	
	/**
	 * Получаем услуги отелей
	 *
	 * @return array - массив данных
	 */
	public function getHotelFacilities() {
		$objCurl = new Service_Curl();
		$arrResult = $objCurl->httpRequest('GET', $this->getBookingPath('getHotelFacilities'), array(
			'city_ids' => $this->arrCityIds, 
			'classes' => $this->arrClasses, 
			'countrycodes' => $this->arrCountryCodes,
			'facilitytype_ids' => $this->arrFacilityTypeIds,
			'hotel_ids' => $this->arrHotelIds,  
			'hotelfacilitytype_ids' => $this->arrHotelFacilityTypeIds, 
			'fields' => $this->arrFields,  
			'rows' => $this->rows, 
			'offset' => $this->offset, 
			'show_test' => $this->showTest,		
			'last_change' => $this->lastChange
		));
		return $this->processResult($arrResult);
	}

	/**
	 * Получаем и сохраняем услуги отелей
	 *
	 */
	public function parseHotelFacilities() {
		$objDB = Service_Database::instance();	
		if (!empty($this->arrHotelIds)) {
			$stmt = "DELETE FROM hotel_facility WHERE ID_hotel IN (" . join(',', $this->arrHotelIds) . ")";
			$objDB->query($stmt);				
		}						
		$count = 0;
		do {			
			$this->offset = $count;	
			$arrHotelFacilities = $this->getHotelFacilities();
			if (empty($arrHotelFacilities) || isset($arrHotelFacilities['fault'])) break;
			foreach ($arrHotelFacilities as $arrHotelFacility) {
				$stmt = "INSERT INTO hotel_facility (`ID_facility_type`,`ID_hotel_facility_type`,`ID_hotel`,`value`) 
								 VALUES ('" . $arrHotelFacility['facilitytype_id'] . "', '" . $arrHotelFacility['hotelfacilitytype_id'] . "', '" . $arrHotelFacility['hotel_id'] . "', '" . $arrHotelFacility['value'] . "')
								 ON DUPLICATE KEY
								 UPDATE 
								 `value` = VALUES(`value`)";
				$objDB->query($stmt);
			}
			$count += sizeof($arrHotelFacilities);
			
		}
		while (sizeof($arrHotelFacilities) == $this->rows);
	}
	
	/**
	 * Получаем услуги типы комнат
	 *
	 * @return array - массив данных
	 */
	public function getRoomTypes() {
		$objCurl = new Service_Curl();
		$arrResult = $objCurl->httpRequest('GET', $this->getBookingPath('getRoomTypes'), array(
			'fields' => $this->arrFields, 
			'languagecodes' => $this->arrLanguageCodes, 
			'roomtype_ids' => $this->arrRoomTypeIds			
		));
		return $this->processResult($arrResult);
	}
	
	/**
	 * Получаем и сохраняем типы комнат
	 *
	 */
	public function parseRoomTypes() {
		$objDB = Service_Database::instance();
		foreach ($this->arrSystemLang as $lang) {
			$this->arrLanguageCodes = array($lang);		
			$arrRoomTypes = $this->getRoomTypes();
			if (empty($arrRoomTypes) || isset($arrRoomTypes['fault'])) continue;
			foreach ($arrRoomTypes as $arrRoomType) {
				$arrRoomType['name'] = Service_Escape::absolutelyEscapeString($arrRoomType['name']);
				$stmt = "INSERT INTO room_type (`ID_room_type`,`room_type_name_" . $lang . "`) 
								 VALUES ('" . $arrRoomType['roomtype_id'] . "', '" . $arrRoomType['name'] . "')
								 ON DUPLICATE KEY UPDATE `room_type_name_" . $lang . "` = '" . $arrRoomType['name'] . "'";
				$objDB->query($stmt);
			}
		}
	}		
	
	/**
	 * Получаем услуги отелей
	 *
	 * @return array - массив данных
	 */
	public function getRooms($maxPersons = null, $roomSize = 1, $showConfiguration = 1) {
		$objCurl = new Service_Curl();
		$arrResult = $objCurl->httpRequest('GET', $this->getBookingPath('getRooms'), array(
			'city_ids' => $this->arrCityIds, 
			'classes' => $this->arrClasses, 
			'countrycodes' => $this->arrCountryCodes,
			'fields' => $this->arrFields,
			'hotel_ids' => $this->arrHotelIds,			
			'max_persons' => $maxPersons,
			'room_ids' => $this->arrRoomIds,
			'roomtype_ids' => $this->arrRoomTypeIds,	  
			'rows' => $this->rows, 
			'offset' => $this->offset, 
			'show_test' => $this->showTest,
			'last_change' => $this->lastChange,
			'show_room_size' => $roomSize,
			'show_configuration' => $showConfiguration		
		));
		return $this->processResult($arrResult);
	}
	
	/**
	 * Получаем и сохраняем услуги отелей
	 *
	 */
	public function parseRooms() {
		$objDB = Service_Database::instance();
				
		$count = 0;
		do {			
			$this->offset = $count;	
			$arrRooms = $this->getRooms();
			if (empty($arrRooms) || isset($arrRooms['fault'])) break;
			foreach ($arrRooms as $key => $arrRoom) {
				$stmt = "INSERT INTO room (`ID_room`,`ID_hotel`,`ID_room_type`,`max_persons`,`min_price`,`max_price`,`room_rank`,`room_size`)
								 VALUES ('" . $arrRoom['room_id'] . "', '" . $arrRoom['hotel_id'] . "', '" . $arrRoom['roomtype_id'] . "', '" . $arrRoom['max_persons'] . "', '" . $arrRoom['min_price'] . "', '" . $arrRoom['max_price'] . "', '" . $arrRoom['ranking'] . "', '" . intval($arrRoom['room_size']) . "')
								 ON DUPLICATE KEY
								 UPDATE 
								 ID_hotel = VALUES(ID_hotel),
								 ID_room_type = VALUES(ID_room_type),
								 max_persons = VALUES(max_persons),
								 min_price = VALUES(min_price),
								 max_price = VALUES(max_price),
								 room_rank = VALUES(room_rank),
								 room_size = VALUES(room_size)";
				$objDB->query($stmt);
				if (isset($arrRoom['bedding'])) {
					if (isset($arrRoom['bedding']['beds'][0])) $arrBeds = $arrRoom['bedding']['beds'];
					else $arrBeds[0] = $arrRoom['bedding']['beds'];
					foreach ($arrBeds as $arrBed) {
						$stmt = "INSERT IGNORE INTO room_bed (`ID_room`,`beds_amount`,`beds_type`,`beds_configuration`)
										 VALUES ('" . $arrRoom['room_id'] . "', '" . $arrBed['amount'] . "', '" . $arrBed['type'] . "', '" . $arrBed['configuration_id'] . "')
										 ";
						$objDB->query($stmt);
					}
					
				}
			}
			$count += sizeof($arrRooms);
			
		}
		while (sizeof($arrRooms) == $this->rows);
		return $arrRooms;
	}

	
	/**
	 * Получаем услуги типы услуг комнат
	 *
	 * @return array - массив данных
	 */
	public function getRoomFacilityTypes() {
		$objCurl = new Service_Curl();
		$arrResult = $objCurl->httpRequest('GET', $this->getBookingPath('getRoomFacilityTypes'), array(
			'facilitytype_ids' => $this->arrFacilityTypeIds,
			'fields' => $this->arrFields, 
			'languagecodes' => $this->arrLanguageCodes, 
			'roomfacilitytype_ids' => $this->arrRoomFacilityTypeIds,
			'types' => $this->arrTypes		
		));
		return $this->processResult($arrResult);
	}
	
	/**
	 * Получаем и сохраняем типы услуг комнат
	 *
	 */
	public function parseRoomFacilityTypes() {
		$objDB = Service_Database::instance();
		foreach ($this->arrSystemLang as $lang) {
			$this->arrLanguageCodes = array($lang);		
			$arrRoomFacilityTypes = $this->getRoomFacilityTypes();
			if (empty($arrRoomFacilityTypes) || isset($arrRoomFacilityTypes['fault'])) continue;
			foreach ($arrRoomFacilityTypes as $arrRoomFacilityType) {
				$arrRoomFacilityType['name'] = Service_Escape::absolutelyEscapeString($arrRoomFacilityType['name']);
				$stmt = "INSERT INTO room_facility_type (`ID_room_facility_type`,`ID_facility_type`,`room_facility_type_type`,`room_facility_type_name_" . $lang . "`) 
								 VALUES ('" . $arrRoomFacilityType['roomfacilitytype_id'] . "','" . $arrRoomFacilityType['facilitytype_id'] . "','" . $arrRoomFacilityType['type'] . "', '" . $arrRoomFacilityType['name'] . "')
								 ON DUPLICATE KEY UPDATE `room_facility_type_name_" . $lang . "` = '" . $arrRoomFacilityType['name'] . "'";
				$objDB->query($stmt);
			}
		}
	}		
	/**
	 * Получаем услуги комнат
	 *
	 * @return array - массив данных
	 */
	public function getRoomFacilities() {
		$objCurl = new Service_Curl();
		$arrResult = $objCurl->httpRequest('GET', $this->getBookingPath('getRoomFacilities'), array(
			'city_ids' => $this->arrCityIds, 
			'classes' => $this->arrClasses, 
			'countrycodes' => $this->arrCountryCodes,
			'facilitytype_ids' => $this->arrFacilityTypeIds,
			'hotel_ids' => $this->arrHotelIds,  
			'hotelfacilitytype_ids' => $this->arrHotelFacilityTypeIds, 
			'fields' => $this->arrFields,  
			'rows' => $this->rows, 
			'offset' => $this->offset, 
			'show_test' => $this->showTest,
			'last_change' => $this->lastChange)
		);
		return $this->processResult($arrResult);
	}
	
	/**
	 * Получаем и сохраняем услуги комнат
	 *
	 */
	public function parseRoomFacilities($arrRooms) {
		$objDB = Service_Database::instance();	
		if (!empty($this->arrHotelIds)) {
			$stmt = "DELETE FROM room_facility WHERE ID_hotel IN (" . join(',', $this->arrHotelIds) . ")";
			$objDB->query($stmt);				
		}						
		$count = 0;
		do {			
			$this->offset = $count;	
			$arrRoomFacilities = $this->getRoomFacilities();
			if (empty($arrRoomFacilities) || isset($arrRoomFacilities['fault'])) break;
			foreach ($arrRoomFacilities as $arrRoomFacility) {
				if (!in_array($arrRoomFacility['room_id'], $arrRooms)) continue;
				$stmt = "INSERT IGNORE INTO room_facility (`ID_room`,`ID_hotel`,`ID_room_facility_type`,`ID_facility_type`,`value`) 
								 VALUES ('" . $arrRoomFacility['room_id'] . "', '" . $arrRoomFacility['hotel_id'] . "', '" . $arrRoomFacility['roomfacilitytype_id'] . "', '" . $arrRoomFacility['facilitytype_id'] . "', '" . $arrRoomFacility['value'] . "')";
				$objDB->query($stmt);
				$stmt = "UPDATE `room`
					SET `str_facilities` = (
						SELECT GROUP_CONCAT(`room_facility`.`ID_room_facility_type`) AS `str_facilities`
    				FROM `room_facility`
    				WHERE `room_facility`.`ID_room` = `room`.`ID_room`
						GROUP BY `ID_room`
					)
					WHERE `room`.`ID_room` = " . intval($arrRoomFacility['room_id']) . "
				";
				$objDB->query($stmt);
			}
			$count += sizeof($arrRoomFacilities);
							
		}
		while (sizeof($arrRoomFacilities) == $this->rows);
	}	
	
/**
	 * Получаем описание комнат
	 *
	 * @return array - массив данных
	 */
	public function getRoomDescriptions() {
		$objCurl = new Service_Curl();
		$arrResult = $objCurl->httpRequest('GET', $this->getBookingPath('getRoomTranslations'), array(
			'hotel_ids' => $this->arrHotelIds, 
			'city_ids' => $this->arrCityIds, 
			'classes' => $this->arrClasses, 
			'countrycodes' => $this->arrCountryCodes,
			'languagecodes' => $this->arrLanguageCodes, 
			'fields' => $this->arrFields, 
			'room_ids' => $this->arrRoomIds, 
			'rows' => $this->rows, 
			'offset' => $this->offset, 
			'show_test' => $this->showTest,
			'last_change' => $this->lastChange)
		);
		return $this->processResult($arrResult);
	}
	
	/**
	 * Получаем и сохраняем описание комнат
	 *
	 */
	public function parseRoomDescriptions($arrRooms) {
		$objDB = Service_Database::instance();		
		if (!empty($this->arrHotelIds)) {
			$stmt = "DELETE FROM room_description WHERE ID_hotel IN (" . join(',', $this->arrHotelIds) . ")";
			$objDB->query($stmt);				
		}							
		foreach ($this->arrSystemLang as $lang) {
			$this->arrLanguageCodes = array($lang);
			$count = 0;				
			do {			
				$this->offset = $count;	
				$arrRoomDescriptions = $this->getRoomDescriptions();
				if (empty($arrRoomDescriptions) || isset($arrRoomDescriptions['fault'])) break;
				foreach ($arrRoomDescriptions as $arrRoomDescription) {
					if (!in_array($arrRoomDescription['room_id'], $arrRooms)) continue;
					$arrRoomDescription['description'] = Service_Escape::absolutelyEscapeString($arrRoomDescription['description']);
					$arrRoomDescription['name'] = Service_Escape::absolutelyEscapeString($arrRoomDescription['name']);
					$stmt = "INSERT INTO room_description (`ID_room`,`ID_hotel`,`room_name_" . $lang . "`,`room_description_" . $lang . "`) 
									 VALUES ('" . $arrRoomDescription['room_id'] . "','" . $arrRoomDescription['hotel_id'] . "', '" . $arrRoomDescription['name'] . "', '" . $arrRoomDescription['description'] . "')
									 ON DUPLICATE KEY UPDATE `room_description_" . $lang . "` = '" . $arrRoomDescription['description'] . "', `room_name_" . $lang . "` = '" . $arrRoomDescription['name'] . "'";
					$objDB->query($stmt);
				}
				$count += sizeof($arrRoomDescriptions);
				
			}
			while (sizeof($arrRoomDescriptions) == $this->rows);
		}
	}			
	
	/**
	 * Получаем фотографии комнат
	 *
	 * @return array - массив данных
	 */
	public function getRoomPhotos() {
		$objCurl = new Service_Curl();
		$arrResult = $objCurl->httpRequest('GET', $this->getBookingPath('getRoomPhotos'), array(
			'hotel_ids' => $this->arrHotelIds, 
			'city_ids' => $this->arrCityIds,
			'room_ids' => $this->arrRoomIds,  
			'classes' => $this->arrClasses, 
			'countrycodes' => $this->arrCountryCodes, 
			'fields' => $this->arrFields,  
			'rows' => $this->rows, 
			'offset' => $this->offset, 
			'show_test' => $this->showTest,
			'last_change' => $this->lastChange)
		);
		return $this->processResult($arrResult);
	}
	
	/**
	 * Получаем и сохраняем фотографии комнат
	 *
	 */
	public function parseRoomPhotos($arrRooms) {
		$objDB = Service_Database::instance();	
		if (!empty($this->arrHotelIds)) {
			$stmt = "DELETE FROM room_photo WHERE ID_hotel IN (" . join(',', $this->arrHotelIds) . ")";
			$objDB->query($stmt);				
		}				
		$count = 0;
		do {			
			$this->offset = $count;	
			$arrRoomPhotos = $this->getRoomPhotos();
			if (empty($arrRoomPhotos) || isset($arrRoomPhotos['fault'])) break;
			/*if (!empty($arrRoomPhotos)) {
				$strRoomPhotoIds = Service_ArrayConverter::getColumnAsString($arrRoomPhotos, 'photo_id');
				$stmt = "SELECT ID_photo FROM room_photo WHERE ID_photo IN (" . $strRoomPhotoIds . ")";
				$arrRoomPhotoIds = $objDB->selectSimpleArray($stmt);
			}		
			else $arrRoomPhotoIds = array();*/
			foreach ($arrRoomPhotos as $arrRoomPhoto) {
				if (!in_array($arrRoomPhoto['room_id'], $arrRooms)) continue;
				$stmt = "INSERT INTO room_photo (`ID_photo`,`ID_room`,`ID_hotel`,`url_original`,`url_max_300`,`url_square_60`) 
								 VALUES ('" . $arrRoomPhoto['photo_id'] . "', '" . $arrRoomPhoto['room_id'] . "', '" . $arrRoomPhoto['hotel_id'] . "', '" . $arrRoomPhoto['url_original'] . "', '" . $arrRoomPhoto['url_max300'] . "', '" . $arrRoomPhoto['url_square60'] . "')
								 ON DUPLICATE KEY
								 UPDATE 
								 `ID_room` = VALUES(`ID_room`),
								 `ID_hotel` = VALUES(`ID_hotel`),
								 `url_original` = VALUES(`url_original`),
								 `url_max_300` = VALUES(`url_max_300`),
								 `url_square_60` = VALUES(`url_square_60`)";
				$objDB->query($stmt);
			}
			$count += sizeof($arrRoomPhotos);
			
		}
		while (sizeof($arrRoomPhotos) == $this->rows);
	}	
	
	
	/**
	 * Получаем логотипы отелей
	 *
	 * @return array - массив данных
	 */
	public function getHotelLogoPhotos() {
		$objCurl = new Service_Curl();
		$arrResult = $objCurl->httpRequest('GET', $this->getBookingPath('getHotelLogoPhotos'), array(
			'hotel_ids' => $this->arrHotelIds, 
			'city_ids' => $this->arrCityIds,
			'room_ids' => $this->arrRoomIds,  
			'countrycodes' => $this->arrCountryCodes, 
			'fields' => $this->arrFields,  
			'rows' => $this->rows, 
			'offset' => $this->offset, 
			'show_test' => $this->showTest,		
			'last_change' => $this->lastChange)
		);
		return $this->processResult($arrResult);
	}
	
	/**
	 * Получаем и сохраняем логотипы отелей
	 *
	 */
	public function parseHotelLogoPhotos() {
		$objDB = Service_Database::instance();	
		if (!empty($this->arrHotelIds)) {
			$stmt = "DELETE FROM hotel_logo WHERE ID_hotel IN (" . join(',', $this->arrHotelIds) . ")";
			$objDB->query($stmt);				
		}				
		$count = 0;
		do {			
			$this->offset = $count;	
			$arrHotelLogoPhotos = $this->getHotelLogoPhotos();
			if (empty($arrHotelLogoPhotos) || isset($arrHotelLogoPhotos['fault'])) break;
			/*if (!empty($arrHotelLogoPhotos)) {
				$strHotelLogoPhotoIds = Service_ArrayConverter::getColumnAsString($arrHotelLogoPhotos, 'photo_id');
				$stmt = "SELECT ID_photo FROM room_photo WHERE ID_photo IN (" . $strHotelLogoPhotoIds . ")";
				$arrHotelLogoPhotoIds = $objDB->selectSimpleArray($stmt);
			}		
			else $arrHotelLogoPhotoIds = array();		*/		
			foreach ($arrHotelLogoPhotos as $arrHotelLogoPhoto) {
				//if (in_array($arrHotelLogoPhoto['photo_id'], $arrHotelLogoPhotoIds)) continue;
				$stmt = "INSERT INTO hotel_logo (`ID_photo`,`ID_hotel`,`url_original`,`url_max_300`,`url_square_60`) 
								 VALUES ('" . $arrHotelLogoPhoto['photo_id'] . "', '" . $arrHotelLogoPhoto['hotel_id'] . "', '" . $arrHotelLogoPhoto['url_original'] . "', '" . $arrHotelLogoPhoto['url_max300'] . "', '" . $arrHotelLogoPhoto['url_square60'] . "')
								 ON DUPLICATE KEY
								 UPDATE 
								 `ID_hotel` = VALUES(`ID_hotel`),
								 `url_original` = VALUES(`url_original`),
								 `url_max_300` = VALUES(`url_max_300`),
								 `url_square_60` = VALUES(`url_square_60`)									 ";
				$objDB->query($stmt);
			}
			$count += sizeof($arrHotelLogoPhotos);
			
		}
		while (sizeof($arrHotelLogoPhotos) == $this->rows);
	}

	/**
	 * Получаем логотипы отелей
	 *
	 * @return array - массив данных
	 */
	public function getHotelPhotos() {
		$objCurl = new Service_Curl();
		$arrResult = $objCurl->httpRequest('GET', $this->getBookingPath('getHotelPhotos'), array(
			'hotel_ids' => $this->arrHotelIds, 
			'city_ids' => $this->arrCityIds,
			'classes' => $this->arrClasses,  
			'countrycodes' => $this->arrCountryCodes, 
			'fields' => $this->arrFields,  
			'rows' => $this->rows, 
			'offset' => $this->offset, 
			'show_test' => $this->showTest,
			'last_change' => $this->lastChange)
		);
		return $this->processResult($arrResult);
	}
	
	/**
	 * Получаем и сохраняем логотипы отелей
	 *
	 */
	public function parseHotelPhotos() {
		$objDB = Service_Database::instance();			
		$count = 0;
		if (!empty($this->arrHotelIds)) {
			$stmt = "DELETE FROM hotel_photo WHERE ID_hotel IN (" . join(',', $this->arrHotelIds) . ")";
			$objDB->query($stmt);
		}
		do {			
			$this->offset = $count;	
			$arrHotelPhotos = $this->getHotelPhotos();		
			if (empty($arrHotelPhotos) || isset($arrHotelPhotos['fault'])) break;
			foreach ($arrHotelPhotos as $arrHotelPhoto) {
				$stmt = "INSERT INTO hotel_photo (`ID_photo`,`ID_hotel`,`url_original`,`url_max_300`,`url_square_60`) 
								 VALUES ('" . $arrHotelPhoto['photo_id'] . "', '" . $arrHotelPhoto['hotel_id'] . "', '" . $arrHotelPhoto['url_original'] . "', '" . $arrHotelPhoto['url_max300'] . "', '" . $arrHotelPhoto['url_square60'] . "')
								 ON DUPLICATE KEY
								 UPDATE 
								 `ID_hotel` = VALUES(`ID_hotel`),
								 `url_original` = VALUES(`url_original`),
								 `url_max_300` = VALUES(`url_max_300`),
								 `url_square_60` = VALUES(`url_square_60`)";
				$objDB->query($stmt);
			}
			$count += sizeof($arrHotelPhotos);				
		}
		while (sizeof($arrHotelPhotos) == $this->rows);
	}

	/**
	 * Получаем услуги типы отелей
	 *
	 * @return array - массив данных
	 */
	public function getHotelTypes() {
		$objCurl = new Service_Curl();
		$arrResult = $objCurl->httpRequest('GET', $this->getBookingPath('getHotelTypes'), array(
			'hoteltype_ids' => $this->arrFacilityTypeIds,
			'fields' => $this->arrFields, 
			'languagecodes' => $this->arrLanguageCodes, 
		));
		return $this->processResult($arrResult);
	}
	
	/**
	 * Получаем и сохраняем типы отелей
	 *
	 */
	public function parseHotelTypes() {
		$objDB = Service_Database::instance();
		foreach ($this->arrSystemLang as $lang) {
			$this->arrLanguageCodes = array($lang);		
			$arrHotelTypes = $this->getHotelTypes();
			if (empty($arrHotelTypes) || isset($arrHotelTypes['fault'])) continue;
			foreach ($arrHotelTypes as $arrHotelType) {
				$arrHotelType['name'] = Service_Escape::absolutelyEscapeString($arrHotelType['name']);
				$stmt = "INSERT INTO hotel_type (`ID_hotel_type`,`hotel_type_name_" . $lang . "`) 
								 VALUES ('" . $arrHotelType['hoteltype_id'] . "', '" . $arrHotelType['name'] . "')
								 ON DUPLICATE KEY UPDATE `hotel_type_name_" . $lang . "` = '" . $arrHotelType['name'] . "'";
				$objDB->query($stmt);
			}
		}
	}

/**
	 * Получаем перводы на языки для отеля
	 *
	 * @return array - массив данных
	 */
	public function getHotelLang() {
		$objCurl = new Service_Curl();
		$arrResult = $objCurl->httpRequest('GET', $this->getBookingPath('getHotelTranslations'), array(
			'hotel_ids' => $this->arrHotelIds, 
			'city_ids' => $this->arrCityIds, 
			'classes' => $this->arrClasses, 
			'countrycodes' => $this->arrCountryCodes,
			'languagecodes' => $this->arrLanguageCodes, 
			'fields' => $this->arrFields, 
			'rows' => $this->rows, 
			'offset' => $this->offset, 
			'show_test' => $this->showTest,
			'last_change' => $this->lastChange)
		);
		return $this->processResult($arrResult);
	}
	
	/**
	 * Получаем и сохраняем перводы на языки для отеля
	 *
	 */
	public function parseHotelLang($lang = 'ru') {
		$objDB = Service_Database::instance();			
		$count = 0;
		$this->arrLanguageCodes = array($lang);		
		do {			
			$this->offset = $count;	
			$arrHotels = $this->getHotelLang();	
			if (empty($arrHotels) || isset($arrHotels['fault'])) break;
			foreach ($arrHotels as $arrHotel) {
				$arrHotel['address'] = Service_Escape::absolutelyEscapeString($arrHotel['address']);
				$arrHotel['name'] = Service_Escape::absolutelyEscapeString($arrHotel['name']);
				$stmt = "UPDATE hotel
				 				 SET address_" . $lang . " = '" . $arrHotel['address'] . "',
				 				 hotel_name_" . $lang . " = '" . $arrHotel['name'] . "'
				 				 WHERE ID_hotel = '" . $arrHotel['hotel_id'] . "'";																										
				$objDB->query($stmt);
			}
			$count += sizeof($arrHotels);
			
		}
		while (sizeof($arrHotels) == $this->rows);
	}			
	
	/**
	 * Получаем ID измененых отелей 
	 * 
	 * @return array - массив данных
	 */
	public function getChangedHotels() {
		$objCurl = new Service_Curl();
		$arrResult = $objCurl->httpRequest('GET', $this->getBookingPath('getChangedHotels'), array(
			'hotel_ids' => $this->arrHotelIds, 
			'city_ids' => $this->arrCityIds,
			'classes' => $this->arrClasses,  
			'countrycodes' => $this->arrCountryCodes, 
			'fields' => $this->arrFields,  
			'rows' => $this->rows, 
			'offset' => $this->offset, 
			'show_test' => $this->showTest,
			'last_change' => $this->lastChange
		));
		return $this->processResult($arrResult);
	}
	
	/**
	 * Получаем всех ID измененых отелей 
	 *
	 */
	public function getAllChangedHotels() {
		$count = 0;
		$arrReturn = array();
		do {			
			$this->offset = $count;	
			$arrHotels = $this->getChangedHotels();
			if (empty($arrHotels) || isset($arrHotels['fault'])) break;
			foreach ($arrHotels as $arrHotel) {
				$arrReturn[] = $arrHotel['hotel_id'];
			}
			$count += sizeof($arrHotels);
			
		}
		while (sizeof($arrHotels) == $this->rows);
		return $arrReturn;
	}

	/**
	 * Получаем отели
	 *
	 * @return array - массив данных
	 */
	public function getHotels() {
		$objCurl = new Service_Curl();
		$arrResult = $objCurl->httpRequest('GET', $this->getBookingPath('getHotels'), array(
			'hotel_ids' => $this->arrHotelIds, 
			'city_ids' => $this->arrCityIds,
			'classes' => $this->arrClasses,  
			'countrycodes' => $this->arrCountryCodes, 
			'fields' => $this->arrFields,  
			'rows' => $this->rows, 
			'offset' => $this->offset, 
			'show_test' => $this->showTest,		
			'last_change' => $this->lastChange)
		);
		return $this->processResult($arrResult);
	}
	
	/**
	 * Получаем и сохраняем логотипы отелей
	 *
	 */
	public function parseHotels() {
		$objDB = Service_Database::instance();			
		$count = 0;
		do {			
			$this->offset = $count;	
			$arrHotels = $this->getHotels();
			if (empty($arrHotels) || isset($arrHotels['fault'])) break;
			$arrCityIds = Service_ArrayConverter::getColumn($arrHotels, 'city_id');
			$stmt = "SELECT ID_city FROM city WHERE ID_city IN (" . join(',', $arrCityIds) . ")";
			$arrDBCityIds = $objDB->selectSimpleArray($stmt);
			if (sizeof($arrDBCityIds) != sizeof($arrCityIds)) { // Если в БД городов меньше
				foreach ($arrHotels as $key => $arrHotel) {
					// Если города нет в БД, то не добавляем этот отель
					if (!in_array($arrHotel['city_id'], $arrDBCityIds)) {
						unset($arrHotels[$key]);
						foreach ($this->arrCityIds as $i => $cityId ) { // Удаляем и из массива для последующих запросов
							if ($cityId == $arrHotel['city_id']) unset($this->arrCityIds[$i]); 
						}
					}
				}
			}
			foreach ($arrHotels as $arrHotel) {
				if ($arrHotel['countrycode'] == 'bi') continue;
				if ($arrHotel['countrycode'] == 'je') continue;	
			  if ($arrHotel['countrycode'] == 'sz')	continue;
							  		
				//if (in_array($arrHotel['hotel_id'], $arrHotelIds)) continue;
				$stmt = "INSERT INTO hotel (
`ID_hotel`,
`ID_hotel_type`,
`ID_city`,
`country_code`,
`address_en`,
`check_in_from`,
`check_in_to`,
`check_out_from`,
`check_out_to`,
`class_is_estimated`,
`class`,
`currency_code`,
`is_closed`,
`latitude`,
`longitude`,
`max_persons_in_reservation`,
`min_rate`,
`max_rate`,
`max_rooms_in_reservation`,
`hotel_name_en`,
`nr_rooms`,
`is_preferred`,
`ranking`,
`review_nr`,
`review_score`,
`url`,
`zip`,
`last_parse`) 
VALUES (
'" . $arrHotel['hotel_id'] . "',
'" . $arrHotel['hoteltype_id'] . "',
'" . $arrHotel['city_id'] . "',
'" . $arrHotel['countrycode'] . "',
'" . Service_Escape::absolutelyEscapeString($arrHotel['address']) . "',
'" . Service_Escape::absolutelyEscapeString($arrHotel['checkin']['from']) . "',
'" . Service_Escape::absolutelyEscapeString($arrHotel['checkin']['to']) . "',
'" . Service_Escape::absolutelyEscapeString($arrHotel['checkout']['from']) . "',
'" . Service_Escape::absolutelyEscapeString($arrHotel['checkout']['to']) . "',
'" . $arrHotel['class_is_estimated'] . "',
'" . $arrHotel['class'] . "',
'" . $arrHotel['currencycode'] . "',
'" . $arrHotel['is_closed'] . "',
'" . $arrHotel['location']['latitude'] . "',
'" . $arrHotel['location']['longitude'] . "',
'" . $arrHotel['max_persons_in_reservation'] . "',
'" . $arrHotel['minrate'] . "',
'" . $arrHotel['maxrate'] . "',
'" . $arrHotel['max_rooms_in_reservation'] . "',
'" . Service_Escape::absolutelyEscapeString($arrHotel['name']) . "',
'" . $arrHotel['nr_rooms'] . "',
'" . $arrHotel['preferred'] . "',
'" . $arrHotel['ranking'] . "',
'" . $arrHotel['review_nr'] . "',
'" . $arrHotel['review_score'] . "',
'" . $arrHotel['url'] . "',
'" . Service_Escape::absolutelyEscapeString($arrHotel['zip']) . "',
'" . Service_Date::gLocalTime2BD() . "'
)
ON DUPLICATE KEY
UPDATE 
`ID_hotel_type` = VALUES(`ID_hotel_type`),
`ID_city` = VALUES(`ID_city`),
`country_code` = VALUES(`country_code`),
`address_en` = VALUES(`address_en`),
`check_in_from` = VALUES(`check_in_from`),
`check_in_to` = VALUES(`check_in_to`),
`check_out_from` = VALUES(`check_out_from`),
`check_out_to` = VALUES(`check_out_to`),
`class_is_estimated` = VALUES(`class_is_estimated`),
`class` = VALUES(`class`),
`currency_code` = VALUES(`currency_code`),
`is_closed` = VALUES(`is_closed`),
`latitude` = VALUES(`latitude`),
`longitude` = VALUES(`longitude`),
`max_persons_in_reservation` = VALUES(`max_persons_in_reservation`),
`min_rate` = VALUES(`min_rate`),
`max_rate` = VALUES(`max_rate`),
`max_rooms_in_reservation` = VALUES(`max_rooms_in_reservation`),
`hotel_name_en` = VALUES(`hotel_name_en`),
`nr_rooms` = VALUES(`nr_rooms`),
`is_preferred` = VALUES(`is_preferred`),
`ranking` = VALUES(`ranking`),
`review_nr` = VALUES(`review_nr`),
`review_score` = VALUES(`review_score`),
`url` = VALUES(`url`),
`zip` = VALUES(`zip`),
`last_parse` = VALUES(`last_parse`)
";
				$objDB->query($stmt);
				$objHotel = new Hotel($arrHotel['hotel_id']);
				$objHotel->updateHotelFinalName();
			}
			$count += sizeof($arrHotels);
			
		}
		while (sizeof($arrHotels) == $this->rows);
		$stmt = "SELECT hotel.ID_hotel, hotel.hotel_name_en FROM hotel WHERE hotel_url IS NULL";
		$arrHotels = $objDB->select($stmt);
		foreach ($arrHotels as $arrHotel) {
			$stmt = "UPDATE hotel 
			SET hotel.hotel_url = '" . Service_Generate::generateAlias($arrHotel['hotel_name_en']) . "'
			WHERE hotel.ID_hotel = '" . $arrHotel['ID_hotel'] . "'";
			$objDB->query($stmt);
		}		
	}
	
	/**
	 * Получаем доступность отелей
	 *
	 * @return array - массив данных
	 */
	public function getHotelAvailability($arrivalDate = '', $departureDate = '', $maxPersons = null, $arrAvailableRooms = array()) {
		$objCurl = new Service_Curl();
		$arrResult = $objCurl->httpRequest('GET', $this->getBookingPath('getHotelAvailability'), array(
			'hotel_ids' => $this->arrHotelIds, 
			'city_ids' => $this->arrCityIds,
			'arrival_date' => $arrivalDate,  
			'departure_date' => $departureDate, 
			'classes' => $this->arrClasses,  
			'max_persons' => -$maxPersons, 
			'show_test' => $this->showTest,
			'available_rooms' => $arrAvailableRooms
		));
		return $this->processResult($arrResult);
	}
	
	/**
	 * Получаем доступность блоков отелей
	 *
	 * @return array - массив данных
	 */
	public function getBlockAvailability($arrivalDate = '', $departureDate = '', $detailLevel = 0, $info = 0) {
		$objCurl = new Service_Curl();
		$arrResult = $objCurl->httpRequest('GET', $this->getBookingPath('getBlockAvailability'), array(
			'hotel_ids' => $this->arrHotelIds, 
			'arrival_date' => $arrivalDate,  
			'departure_date' => $departureDate, 
			'important_information' => $info,
			'show_test' => $this->showTest,		
			'detail_level' => $detailLevel,
			'languagecode' => $this->arrLanguageCodes
		));
		return $this->processResult($arrResult);
	}
	
	/**
	 * Бронируем отель
	 *
	 * @return array - массив данных
	 */
	public function processBooking(Booking $objBooking, $dateArr, $dateDep, $hotelId) {
		Service_Debug::setDebug();
		list($expMonth, $expYear) = explode('/', $objBooking->getField('cc_expiration_date'));
		$arrBlockIds = Service_ArrayConverter::getColumn($objBooking->tableFields['Room'], 'ID_block');
		$arrBlockQty = Service_ArrayConverter::getRepeats($arrBlockIds);
		$objCurl = new Service_Curl();
		$objCurl->useSSL = true;
		$arrResult = $objCurl->httpRequest('GET', $this->getBookingPath('processBooking', 1), array(
			'affiliate_id' => 319657,
			//'affiliate_label' => '',
			'guest_city' => $objBooking->getField('city'), 
			'guest_email' => (defined('MAIL_CLASS_DEFINED') ? 'slamer86@gmail.com' : Service_Generate::generateAlias($objBooking->getField('booker_last_name') . ' ' . $objBooking->getField('booker_first_name')) . '@' . substr(str_replace(array('http://', 'www.'), '', W_FULLPATH), 0, -1)),
			//'guest_email' => $objBooking->getField('e_mail'),			
			//'guest_email' => 'slamer86@gmail.com',			
			'guest_country' => $objBooking->getField('country_code'),
			'begin_date' => Service_Date::dateToBD($dateArr),
			'block_id' => array_unique($arrBlockIds),
			'block_qty' => $arrBlockQty,
			'cc_cardholder' => $objBooking->getField('booker_last_name') . ' ' . $objBooking->getField('booker_first_name'), 
			'cc_cvc' => $objBooking->getField('cc_cvc'),
			'cc_expiration_date' => '20' . $expYear . '-' . $expMonth . '-01',
			'cc_number' => $objBooking->getField('cc_number'),
			'cc_type' => $objBooking->getField('ID_credit_card'),
			'comments' => $objBooking->getField('comment'),
			'dc_issue_number' => null, 
			'dc_start_date' => null,
			'end_date' => Service_Date::dateToBD($dateDep),
			'guest_language' => null,
			'guest_name' => Service_ArrayConverter::getColumn($objBooking->tableFields['Room'], 'guest_name'),
			'guest_qty' => Service_ArrayConverter::getColumn($objBooking->tableFields['Room'], 'guest_qty'),
			'guest_street' => $objBooking->getField('address'),
			'guest_telephone' => $objBooking->getField('home_phone'),
			'guest_zip' => $objBooking->getField('zip'),
			'hotel_id' => $hotelId,
			'incremental_prices' => Service_ArrayConverter::getColumn($objBooking->tableFields['Room'], 'price'),
			'show_test' => $this->showTest,
			'test_mode' => $this->test, 
			'smoking' => Service_ArrayConverter::getColumn($objBooking->tableFields['Room'], 'smoking'),			
		));
		$arrResult =  $this->processResult($arrResult);
		if (isset($arrResult['fault'])) {
			$objError = new Error();
		  $objError->setFields(array('error_name' => 'processBooking', 'error_text' => Service_Escape::absolutelyEscapeString($arrResult['fault']['string'])));
		  $objError->save();
		}
		return $arrResult;
	}	

	/**
	 * Бронируем отель
	 *
	 * @return array - массив данных
	 */
	public function cancelBooking($bookingId, $pincode, $reason = 'Reason') {
		Service_Debug::setDebug();
		$objCurl = new Service_Curl();
		$objCurl->useSSL = true;
		$arrResult = $objCurl->httpRequest('GET', $this->getBookingPath('cancelBooking', 1), array(
			'id' => $bookingId,
			'pincode' => $pincode, 
			'reason' => $reason,			
		));
		return $this->processResult($arrResult);
	}		
	
	/**
	 * Парсим информацию о детских и дополнительных кроватях
	 * 
	 * @param string $policyText - текст с информацией о кроватях
	 * @return $arrChildren - массив с информацией о кроватях
	 */
	public function parseChildrenPolicy($policyText) {
		Service_Debug::setDebug();
		$arrChildren = array();
		echo str_replace('.', '.<br>', $policyText ) . '<br>';
		if (preg_match('|Children cannot be accommodated at the hotel|', $policyText)) $arrChildren['welcome'] = 0;
		elseif (preg_match('|All children are welcome|', $policyText)) $arrChildren['welcome'] = 1;
		elseif (preg_match('|Children older than ([0-9]+) years are welcome|', $policyText, $arrYears)) {
			$arrChildren['welcome'] = 2;
			$arrChildren['years'] = $arrYears[1];
		}
		else $arrChildren['welcome'] = 3;
// Существующие кровати
		$arrChildren['existing'] = array();
		preg_match('#(All|One|Up to two)( further)? child(ren)? under ([0-9]+) years stay(s)? free of charge when using existing beds#', $policyText, $arrExistingBeds);
		if (isset($arrExistingBeds[0])) {
			$i = sizeof($arrChildren['existing']);
			$arrChildren['existing'][$i]['from'] = 0;
			$arrChildren['existing'][$i]['to'] = $arrExistingBeds[4];
			$arrChildren['existing'][$i]['price'] = 0;
			$arrChildren['existing'][$i]['num'] = ($arrExistingBeds[1] == 'One') ? 1 : (($arrExistingBeds[1] == 'Up to two') ? 2 : 10);
		}
		preg_match('#(All|One|Up to two)( further)? child(ren)? from ([0-9]+) to ([0-9]+) years stay(s)? free of charge when using existing beds#', $policyText, $arrExistingBeds);
		//                                                   One child from 0 to 7 years stays free of charge when using existing beds
		if (isset($arrExistingBeds[0])) {
			$i = sizeof($arrChildren['existing']);
			$arrChildren['existing'][$i]['from'] = $arrExistingBeds[4];
			$arrChildren['existing'][$i]['to'] = $arrExistingBeds[5];
			$arrChildren['existing'][$i]['price'] = 0;
			$arrChildren['existing'][$i]['num'] = ($arrExistingBeds[1] == 'One') ? 1 : (($arrExistingBeds[1] == 'Up to two') ? 2 : 10);
		}		
		preg_match('#(All|One|Up to two)( further)? child(ren)? from ([0-9]+) to ([0-9]+) years (are|is) charged ([A-Z]{3}) ([0-9\.]+) [\w ]+ existing bed#', $policyText, $arrExistingBeds);
		if (!isset($arrExistingBeds[0])) preg_match('#(All|One|Up to two)( further)? child(ren)? from ([0-9]+) to ([0-9]+) years (are|is) charged ([0-9]+) (%)+ [\w ]+ existing bed#', $policyText, $arrExistingBeds);
		if (isset($arrExistingBeds[0])) {
			$i = sizeof($arrChildren['existing']);
			$arrChildren['existing'][$i]['from'] = $arrExistingBeds[4];
			$arrChildren['existing'][$i]['to'] = $arrExistingBeds[5];
			$arrChildren['existing'][$i]['num'] = ($arrExistingBeds[1] == 'One') ? 1 : (($arrExistingBeds[1] == 'Up to two') ? 2 : 10);
			if ($arrExistingBeds[8] == '%')	$arrChildren['existing'][$i]['percent'] = $arrExistingBeds[7];
		}				
		preg_match('#(All|One|Up to two)( further)? older child(ren)? or adult(s)? (are|is) charged ([A-Z]{3}) ([0-9\.]+) [\w ]+ existing bed#', $policyText, $arrExistingBeds);
		if (!isset($arrExistingBeds[0])) preg_match('#(All|One|Up to two)( further)? older child(ren)? or adult(s)? (are|is) charged ([0-9]+) (%) [\w ]+ existing bed#', $policyText, $arrExistingBeds);
		if (isset($arrExistingBeds[0])) {
			$i = sizeof($arrChildren['existing']);
			$max = 0;
			foreach ($arrChildren['existing'] as $extraBed) {
				$max = max($max, $extraBed['to']);
			}			
			$arrChildren['existing'][$i]['from'] = $max + 1;
			$arrChildren['existing'][$i]['to'] = 999;
			
			if ($arrExistingBeds[7] == '%')	$arrChildren['existing'][$i]['percent'] = $arrExistingBeds[6];
			else {
				$arrChildren['existing'][$i]['price'] = $arrExistingBeds[7];
				$arrChildren['existing'][$i]['curency'] = $arrExistingBeds[6];
			}
		}
// Детские кровати
		$arrChildren['cots'] = array();
		preg_match('#(All|One|Up to two)( further)? child(ren)? under ([0-9]+) years stay(s)? free of charge [\w ]+ cot#', $policyText, $arrCots);
		if (!isset($arrCots[0])) preg_match('#(All|One|Up to two)( further)? child(ren)? under ([0-9]+) years (is|are) charged ([A-Z]{3}) ([0-9\.]+) [\w ]+ cot#', $policyText, $arrCots);
		if (isset($arrCots[0])) {
			$arrChildren['cots']['from'] = 0;
			$arrChildren['cots']['to'] = $arrCots[4];
			$arrChildren['cots']['num'] = ($arrCots[1] == 'One') ? 1 : (($arrCots[1] == 'Up to two') ? 2 : 10);
			$arrChildren['cots']['allow'] = 1;
			if (isset($arrCots[7])) {
				$arrChildren['cots']['currency'] = $arrCots[6];
				$arrChildren['cots']['price'] = $arrCots[7];				
			}
			else $arrChildren['cots']['price'] = 0;
		}
// Дополнительные кровати
		$arrChildren['extra'] = array();
		//One child under 12 years stays free of charge in an extra bed.
		preg_match('#(All|One|Up to two)( further)? child(ren)? under ([0-9]+) years stays free of charge in an extra bed#', $policyText, $arrExtraBeds);
		if (isset($arrExtraBeds[0])) {
			$i = sizeof($arrChildren['extra']);
			$arrChildren['extra'][$i]['from'] = 0;
			$arrChildren['extra'][$i]['to'] = $arrExtraBeds[4];
			$arrChildren['extra'][$i]['num'] = ($arrExtraBeds[1] == 'One') ? 1 : (($arrExtraBeds[1] == 'Up to two') ? 2 : 10);
			$arrChildren['extra'][$i]['price'] = 0;
		}		
		preg_match('#(All|One|Up to two)( further)? child(ren)? from ([0-9]+) to ([0-9]+) years (are|is) charged ([A-Z]{3}) ([0-9\.]+) [\w ]+ extra bed#', $policyText, $arrExtraBeds);
		if (!isset($arrExtraBeds[0])) preg_match('#(All|One|Up to two)( further)? child(ren)? from ([0-9]+) to ([0-9]+) years (are|is) charged ([0-9]+) (%)+ [\w ]+ extra bed#', $policyText, $arrExtraBeds);
		if (isset($arrExtraBeds[0])) {
			$i = sizeof($arrChildren['extra']);
			$arrChildren['extra'][$i]['from'] = $arrExtraBeds[4];
			$arrChildren['extra'][$i]['to'] = $arrExtraBeds[5];
			$arrChildren['extra'][$i]['num'] = ($arrExtraBeds[1] == 'One') ? 1 : (($arrExtraBeds[1] == 'Up to two') ? 2 : 10);
			if ($arrExtraBeds[8] == '%') $arrChildren['extra'][$i]['percent'] = $arrExtraBeds[7];
			else {
				$arrChildren['extra'][$i]['currency'] = $arrExtraBeds[7];
				$arrChildren['extra'][$i]['price'] = $arrExtraBeds[8];
			}
		}
		preg_match('#(All|One|Up to two)( further)?( older)? child(ren)? or adult(s)? (are|is) charged ([A-Z]{3}) ([0-9\.]+) [\w ]+ extra bed#', $policyText, $arrExtraBeds);
		if (!isset($arrExtraBeds[0])) preg_match('#(All|One|Up to two)( further)?( older)? child(ren)? or adult(s)? (are|is) charged ([0-9]+) (%)+ [\w ]+ extra bed#', $policyText, $arrExtraBeds);
		if (isset($arrExtraBeds[0])) {
			$i = sizeof($arrChildren['extra']);
			$max = 0;
			foreach ($arrChildren['existing'] as $extraBed) {
				if ($extraBed['to'] != 999) $max = max($max, $extraBed['to']);
			}
			if (isset($arrChildren['cots']['to']) && $arrChildren['cots']['to'] != 999) $max = max($max, $arrChildren['cots']['to']);	
			foreach ($arrChildren['extra'] as $extraBed) {
				if ($extraBed['to'] != 999) $max = max($max, $extraBed['to']);
			}
			if (isset($arrChildren['years'])) $max = $arrChildren['years'] - 1;
			$arrChildren['extra'][$i]['from'] = $max + 1;
			$arrChildren['extra'][$i]['to'] = 999;			
			$arrChildren['extra'][$i]['num'] = ($arrExtraBeds[1] == 'One') ? 1 : (($arrExtraBeds[1] == 'Up to two') ? 2 : 10);
			if ($arrExtraBeds[8] == '%') {
				$arrChildren['extra'][$i]['percent'] = $arrExtraBeds[7];
			}
			else {
				$arrChildren['extra'][$i]['currency'] = $arrExtraBeds[7];
				$arrChildren['extra'][$i]['price'] = $arrExtraBeds[8];
			}		
		}
// Вместимость
		preg_match_all('#Maximum capacity of ([\w \/]+) in a room is ([0-9]+)#', $policyText, $arrCapacity);
		if (isset($arrCapacity[0][0])) {
			foreach ($arrCapacity[1] as $bedKey => $bedName) {
				$arrChildren['capacity'][$bedName] = $arrCapacity[2][$bedKey];
				switch ($bedName) {
					case 'extra beds/babycots':
						foreach ($arrChildren['extra'] as $key => $value) {
							$arrChildren['extra'][$key]['num'] = $arrCapacity[2][$bedKey];
						}
						$arrChildren['cots']['num'] = $arrCapacity[2][$bedKey];
						/*foreach ($arrChildren['cots']['years'] as $key => $value) {
							$arrChildren['cots']['years'][$key]['num'] = $arrCapacity[2][$key];
						}*/
						
						break;
					case 'babycots':
						/*foreach ($arrChildren['cots']['years'] as $key => $value) {
							$arrChildren['cots']['years'][$key]['num'] = $arrCapacity[2][$key];
						}*/
						$arrChildren['cots']['num'] = $arrCapacity[2][$bedKey];
						break;
					case 'extra beds':
						foreach ($arrChildren['extra'] as $key => $value) {
							$arrChildren['extra'][$key]['num'] = $arrCapacity[2][$bedKey];
						}
						break;
				}	
			}			
		}
		else $arrChildren['capacity'] = 0;

		return $arrChildren;
	}	

	
	/**
	 * Генерируем URL для отелей
	 */	
	public function parseChangedHotels($countryCode = null) {
		Service_Debug::setDebug();
		$objDB = Service_Database::instance();
		if (empty($this->lastChange)) $this->lastChange = date('Y-m-d', time() - 24 * 3600);
		echo $this->lastChange;
		if (empty($countryCode)) {			
			$stmt = "SELECT country_code FROM country";
			$arrCountryCodes = $objDB->selectSimpleArray($stmt);
		}
		else {
			$arrCountryCodes = array($countryCode);
		}
		$counter = 0;	
		
		foreach ($arrCountryCodes as $countryCode) {
			$this->arrCountryCodes = array($countryCode);
			$arrHotelIds = $this->getAllChangedHotels();
			if (empty($arrHotelIds) || isset($arrHotelIds['fault'])) continue;
			foreach ($arrHotelIds as $hotelId) {
				$stmt = "INSERT IGNORE INTO changed_hotel (
									ID_hotel, 
									country_code, 
									is_new, 
									created_at
								 ) 
							   VALUES (
							   	'" . $hotelId . "', 
							   	'" . $countryCode . "', 
							   	IF((SELECT ID_hotel FROM hotel WHERE ID_hotel = '" . $hotelId . "') IS NULL, 1, 0),
							   	'" . Service_Date::gLocalTime2BD() . "'
							   )";
				$objDB->query($stmt);				
			}			
		}
		$stmt = "SELECT ID_hotel FROM changed_hotel WHERE is_new = 1";
		$arrHotelIds = $objDB->selectSimpleArray($stmt);
		foreach ($arrHotelIds as $hotelId) {
			$stmt = "INSERT IGNORE INTO hotel (ID_hotel) VALUES ('" . $hotelId . "')";
			$objDB->query($stmt);
		}				
	}
	/**
	 * Генерируем URL для отелей
	 */	
	public function updateChangedHotels($timeLimit = 35) {
		Pressure::setStart();
		$objDB = Service_Database::instance();
		$stmt = "SELECT ID_hotel FROM changed_hotel
			       ORDER BY is_new DESC, IF(country_code = 'ru', 1, 0) DESC, created_at LIMIT 1000";
		$arrHotelIds = $objDB->selectSimpleArray($stmt);
		$size = sizeof($arrHotelIds);
		$pages = ceil($size/50);
		for ($i = 0; $i < $pages; $i++) {
			echo $i . "\n";
			$arrSliceHotelIds = Service_ArrayConverter::getArraySlice($arrHotelIds, $i * 50, 50);
			$this->arrHotelIds = $arrSliceHotelIds;
			$this->parseHotels();
			$stmt = "DELETE FROM changed_hotel WHERE ID_hotel IN (" . join(',', $arrSliceHotelIds) . ")";
			$objDB->query($stmt);			
			$stmt = "DELETE FROM hotel WHERE ID_hotel IN (" . join(',', $arrSliceHotelIds) . ") AND country_code IS NULL";
			$objDB->query($stmt);
			$stmt = "SELECT ID_hotel FROM hotel WHERE ID_hotel IN (" . join(',', $this->arrHotelIds) . ")";
			$this->arrHotelIds = $objDB->selectSimpleArray($stmt);
			if (!sizeof($this->arrHotelIds)) continue;
			$this->parseHotelDescriptions();
			$this->parseHotelDescriptionPhotos();
			$this->parseHotelFacilities();
			$this->parseHotelLang('ru');
			$this->parseHotelPhotos();
			$this->parseHotelLogoPhotos();
			$arrRooms = $this->parseRooms();
			if ($arrRooms) {
				$arrRooms = Service_ArrayConverter::getColumn($arrRooms, 'room_id');				
				$this->parseRoomDescriptions($arrRooms); 
				$this->parseRoomFacilities($arrRooms);
				$this->parseRoomPhotos($arrRooms);
			}
			$this->arrHotelIds = array();
			$time = Pressure::calculateCurrentDuration();
			echo $i . ' - ' . $time . "\n";
			if ($time > $timeLimit) return true;						
		}			
	}
	
	public function updateAdditionalInfo() {
		Service_Debug::setDebug();
		if (empty($this->lastChange)) $this->lastChange = date('Y-m-d', time() - 24 * 3600);
		$this->parseDistrictHotels();
		$this->parseRegionHotels();		
	}
	
	public function parseErrors($error) {
		Service_Debug::setDebug();
		$i = 0;
		$arrReturn = array();		
		if (preg_match('#guest_email#', $error)) {
			$arrReturn[++$i]['name'] = 'e_mail';
			$arrReturn[$i]['text'] = 'E-Mail';
		}
		if (preg_match('#guest_telephone#', $error)) {
			$arrReturn[++$i]['name'] = 'home_phone';
			$arrReturn[$i]['text'] = 'Телефон';
		}
		if (preg_match('#cc_type#', $error)) {
			$arrReturn[++$i]['name'] = 'ID_credit_card';
			$arrReturn[$i]['text'] = Service_Translate::getText('Тип кредитной карты');
		}		
		if (preg_match('#cc_number#', $error)) {
			$arrReturn[++$i]['name'] = 'cc_number';
			$arrReturn[$i]['text'] = Service_Translate::getText('Номер карты');
		}		
		if (preg_match('#cc_cvc#', $error)) {
			$arrReturn[++$i]['name'] = 'cc_cvc';
			$arrReturn[$i]['text'] = Service_Translate::getText('Код безопасности');
		}
		if (preg_match('#cc_expiration_date#', $error)) {
			$arrReturn[++$i]['name'] = 'cc_year';
			$arrReturn[$i]['text'] = Service_Translate::getText('Дата истечения срока действия');
		}


		return $arrReturn;
	}

	public function getHotelBookingInfo($dateArr, $dateDep, $hotelId, $blockId) {
		Service_Debug::setDebug();
		$language = Service_Translate::getLang();
		$arrReturn = array();
		
	  // Получаем инфу по отелю (для инфы об отмене бронирования)
	  $objServiceBooking = new Service_Booking();
		$objServiceBooking->arrHotelIds[] = $hotelId;
	  $objServiceBooking->arrLanguageCodes = array($language);
	  $arrResult = $objServiceBooking->getBlockAvailability(Service_Date::dateToBD($dateArr), Service_Date::dateToBD($dateDep), 1, 1);

	  if (empty($arrResult) || isset($arrResult['fault'])) return array('cancellation' => '', 'deposit_required' => '', 'block' => array());
	  
  	if (isset($arrResult[0]['block'][0])) $arrBlocks = $arrResult[0]['block'];
  	elseif (isset($arrResult[0]['block'])) $arrBlocks[0] = $arrResult[0]['block'];
  		  
		foreach ($arrBlocks as $arrBlock) {
			if (!empty($arrBlock)) {
				if (isset($arrBlock['incremental_price'][0])) $arrPrices = $arrBlock['incremental_price'];
				else $arrPrices[0] = $arrBlock['incremental_price'];					
				$arrReturn['block'][$arrBlock['block_id']]['price'] = $arrPrices[0]['price'];
				$arrReturn['block'][$arrBlock['block_id']]['currency'] = $arrPrices[0]['currency'];
				$arrReturn['block'][$arrBlock['block_id']]['bb'] = $arrBlock['breakfast_included'] ? 1 : 0;
				$arrReturn['block'][$arrBlock['block_id']]['dr'] = $arrBlock['deposit_required'] ? 1 : 0;
				$arrReturn['block'][$arrBlock['block_id']]['free'] = $arrBlock['refundable'] ? 1 : 0;
				$arrReturn['block'][$arrBlock['block_id']]['text'] = $arrBlock['block_text'];
				preg_match_all('|div class="POLICY_CANCELLATION"\>(.+)|', $arrBlock['block_text'], $arrText);
	  		if (!empty($arrText[1][0])) {
	  			$arrReturn['block'][$arrBlock['block_id']]['cancellation'] = Service_Escape::absolutelyEscapeString(str_replace('</div>', '', $arrText[1][0]));
	  		}
			}
		}	  
	  
	  
	  
  	$arrReturn['policies'] = $arrResult[0]['hotel_text']; 	  	
	  $arrBlocks = Service_ArrayConverter::makeKeyArrayFromMultyArray($arrBlocks, 'block_id');
	  $refundable = '';
	  
	  if (!empty($arrBlocks[$blockId])) {
	  	
	  	preg_match_all('|div class="POLICY_CANCELLATION"\>(.+)|', $arrBlocks[$blockId]['block_text'], $arrText);
	  	if (!empty($arrText[1][0])) {
	  		$cancellation = $arrText[1][0];
	  	}
	  	/*if ($arrCancellation[$blockId]['refundable']) {
	  		$refundable = Service_Translate::getText('За отмену или изменения заказов...', $arrCancellation[$blockId]['refundable_until']);
	  	} */
	  	$arrReturn['deposit_required'] = $arrBlocks[$blockId]['deposit_required'];
	  }
	  if (empty($cancellation)) {
	  	preg_match_all('|div class="POLICY_CANCELLATION"\>(.+)|', $arrReturn['policies'], $arrText);
	  	if (!empty($arrText[1][0])) $cancellation = $arrText[1][0];
	  }	
	  	
	  $arrReturn['cancellation'] = empty($cancellation) ? '' : Service_Escape::absolutelyEscapeString(str_replace('</div>', '', $cancellation));
	  return $arrReturn;
	}	
	
}
?>